package com.meshnetics.gb.util;

/**
 * Some commonly useful conversions.
 *
 * @author Yury Aserchev (yaserchev@meshnetics.com)
 * @author Pavlov Dmitry (dpavlov@meshnetics.com)
 */
public final class Conversions {
    /** Hex number prefix */
    public static final String HEX_PREFIX = "0x";
    /** Byte mask & u-byte max value */
    public static final int BYTE_MASK = 0xFF;
    /** Short mask & u-short max value */
    public static final int SHORT_MASK = 0xFFFF;
    private static final int INT_LENGTH_IN_BITS = 4 * 8;

    /** Private constructor - no class instances at all */
    private Conversions() {
    }

    /**
     * Returns expanded byte to u-byte value as int.
     *
     * @param b source byte value.
     * @return result u-byte value.
     */
    public static int expandByteToInt(byte b) {
        return b & BYTE_MASK;
    }

    /**
     * Returns expanded short to u-short value as int.
     *
     * @param sh source short value.
     * @return result u-short value.
     */
    public static int expandShortToInt(final short sh) {
        return sh & Conversions.SHORT_MASK;
    }

    /**
     * Returns expanded int to u-int value as long
     * @param integer source int value
     * @return result u-int value
     */
    public static long expandIntToLong(final int integer) {
        return transferBits(integer, 0, INT_LENGTH_IN_BITS);
    }

    /**
     * Performs transfering selected range of bits from one integer (passed as long)
     * to another integer (long too). This method can be used for converting signed value
     * to uunsigned. Transfering performs from less significant bit to most.
     * @param number value who's range of bits must be transfered.
     * @param startPosition start bit of transfering
     * @param length the length of range
     * @return value that contain only cpecified transfered bits
     */
    public static long transferBits(long number, int startPosition, int length) {                
        long mask = 1 << startPosition;
        long result = 0;
        for (int i = 0; i < length; i++) {
            result = result | (number & mask);
            mask = mask << 1;
        }
        return result;
    }
}
